home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEX-UTIL / DVIPS_55 / dvips / src / c / bbox < prev    next >
Text File  |  1994-05-06  |  9KB  |  277 lines

  1. /*
  2.  *   Calculates the bounding box for a one-page .dvi file.
  3.  *   Based on a lot of other dvips stuff.  Requires a total re-scan
  4.  *   of the page.
  5.  *
  6.  *   If you request an EPSF file and specify -a, you may end up
  7.  *   processing a single page four times!
  8.  */
  9. #include "dvips.h"
  10. extern char *mymalloc() ;
  11. extern integer scalewidth() ;
  12. extern void tfmopen(), skipover(), error() ;
  13. extern shalfword tfmbyte(), dvibyte(), signedbyte(), signedpair() ;
  14. extern halfword tfm16(), twobytes() ;
  15. extern integer tfm32(), threebytes(), signedtrio(), signedquad() ;
  16. extern double floor() ;
  17.  
  18. extern char *nextstring, errbuf[] ;
  19. extern FILE *tfmfile, *dvifile ;
  20. extern fontdesctype *baseFonts[] ;
  21. extern integer firstboploc, num, den, mag ;
  22. extern integer hoff, voff ;
  23.  
  24. typedef struct {
  25.    integer llx, lly, urx, ury ;
  26. } bbchardesctype ;
  27. typedef struct {
  28.    bbchardesctype bbchardesc[256] ;
  29. } bbfontdesctype ;
  30.  
  31. static bbfontdesctype *bbaseFonts[256] ;
  32.  
  33. integer nscalewidth(a, b)
  34. register integer a, b ;
  35. {
  36.    if (a < 0)
  37.       return - nscalewidth(-a, b) ;
  38.    else if (b < 0)
  39.       return - scalewidth(a, -b) ;
  40.    else
  41.       return scalewidth(a, b) ;
  42. }
  43.  
  44. void bbtfmload(n)
  45. int n ;
  46. {
  47.    register shalfword i ;
  48.    register integer li ;
  49.    integer scaledsize ;
  50.    shalfword nw, nh, nd, ns, hd ;
  51.    shalfword bc, ec ;
  52.    integer scaled[300] ;
  53.    integer chardat[256] ;
  54.    integer slant = 0 ;
  55.    bbchardesctype *cc ;
  56.    register fontdesctype *curfnt = baseFonts[n] ;
  57.    register bbfontdesctype *bbcurfnt =
  58.       (bbfontdesctype *)mymalloc(sizeof(bbfontdesctype)) ;
  59.  
  60.    bbaseFonts[n] = bbcurfnt ;
  61.    tfmopen(curfnt) ;
  62. /*
  63.  *   Next, we read the font data from the tfm file, and store it in
  64.  *   our own arrays.
  65.  */
  66.    li = tfm16() ; hd = tfm16() ;
  67.    bc = tfm16() ; ec = tfm16() ;
  68.    nw = tfm16() ; nh = tfm16() ; nd = tfm16() ;
  69.    ns = tfm16() ;
  70.    ns += tfm16() ;
  71.    ns += tfm16() ;
  72.    ns += tfm16() ;
  73.    li = tfm16() ;
  74.    li = tfm32() ;
  75.    if (li && curfnt->checksum)
  76.       if (li!=curfnt->checksum) {
  77.          (void)sprintf(errbuf,"Checksum mismatch in %s", curfnt->name) ;
  78.          error(errbuf) ;
  79.        }
  80.    li = tfm32() ;
  81.    for (i=2; i<hd; i++)
  82.       li = tfm32() ;
  83.    for (i=0; i<256; i++)
  84.       chardat[i] = -1 ;
  85.    for (i=bc; i<=ec; i++) {
  86.       chardat[i] = tfm16() ;
  87.       li = tfm16() ;
  88.    }
  89.    scaledsize = curfnt->scaledsize ;
  90.    for (i=0; i<nw + nh + nd; i++)
  91.       scaled[i] = scalewidth(tfm32(), scaledsize) ;
  92.    for (i=0; i<ns; i++)
  93.       tfm32() ;
  94.    slant = tfm32() ;
  95.    (void)fclose(tfmfile) ;
  96.    for (i=0; i<256; i++) {
  97.       cc = &(bbcurfnt->bbchardesc[i]) ;
  98.       if (chardat[i] != -1) {
  99.          cc->ury = scaled[((chardat[i] >> 4) & 15) + nw] ;
  100.          cc->lly = - scaled[(chardat[i] & 15) + nw + nh] ;
  101.          cc->llx = 0 ;
  102.          cc->urx = curfnt->chardesc[i].TFMwidth ;
  103.       } else {
  104.          cc->llx = cc->lly = cc->urx = cc->ury = 0 ;
  105.       }
  106.    }
  107.    if (slant) {
  108.       for (i=0; i<256; i++) {
  109.          cc = &(bbcurfnt->bbchardesc[i]) ;
  110.          cc->llx += nscalewidth(cc->lly, slant) ;
  111.          cc->urx += nscalewidth(cc->ury, slant) ;
  112.       }
  113.    }
  114. }
  115. extern struct dvistack {
  116.   integer hh, vv ;
  117.   integer h, v, w, x, y, z ;
  118. } stack[] ;
  119. static integer llx, lly, urx, ury ;
  120. void bbdopage()
  121. {
  122.    register shalfword cmd ;
  123.    register bbchardesctype *bcd ;
  124.    register chardesctype *cd ;
  125.    register integer h ;
  126.    integer fnt ;
  127.    int charmove ;
  128.    struct dvistack *sp = stack ;
  129.    integer v, w, x, y, z ;
  130.    register fontdesctype *curfnt = 0 ;
  131.    register bbfontdesctype *bbcurfnt = 0 ;
  132.  
  133.    w = x = y = z = 0 ;
  134.    h = 0 ; v = 0 ;
  135.    llx = lly = 1000000000 ;
  136.    urx = ury = -1000000000 ;
  137.    charmove = 0 ;
  138.    while (1) {
  139.       switch (cmd=dvibyte()) {
  140. case 138: break ;
  141. case 133: /* put1 */
  142.          cmd = dvibyte() ;
  143.          charmove = 0 ;
  144.          goto dochar ;
  145. case 128: cmd = dvibyte() ; /* set1 command drops through to setchar */
  146. default: /* these are commands 0 (setchar0) thru 127 (setchar127) */
  147.          charmove = 1 ;
  148. dochar:
  149.          cd = &(curfnt->chardesc[cmd]) ;
  150.          bcd = &(bbcurfnt->bbchardesc[cmd]) ;
  151.          if (h + bcd->llx < llx) llx = h + bcd->llx ;
  152.          if (h + bcd->urx > urx) urx = h + bcd->urx ;
  153.          if (v - bcd->ury < lly) lly = v - bcd->ury ;
  154.          if (v - bcd->lly > ury) ury = v - bcd->lly ;
  155.          if (charmove)
  156.             h += cd->TFMwidth ;
  157.          break ;
  158. case 129: case 130: case 131: case 134: case 135: case 136: case 139: 
  159. case 247: case 248: case 249: case 250: case 251: case 252: case 253:
  160. case 254: case 255: /* unimplemented or illegal commands */
  161.          error("! synch") ;
  162. case 132: case 137: /* rules */
  163.          {  integer ry, rx ;
  164.             ry = signedquad() ; rx = signedquad() ;
  165.             if (rx>0 && ry>0) {
  166.                if (h < llx) llx = h ;
  167.                if (v - ry < lly) lly = v - ry ;
  168.                if (h + rx > urx) urx = h + rx ;
  169.                if (v > ury) ury = v ;
  170.             } else
  171.                rx = 0 ;
  172.             if (cmd != 137)
  173.                h += rx ;
  174.             break ;
  175.          }
  176. case 141: /* push */
  177.          sp->h = h ; sp->v = v ;
  178.          sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
  179.          if (++sp >= &stack[STACKSIZE]) error("! Out of stack space") ;
  180.          break ;
  181. case 140: /* eop or end of virtual character */
  182.          return ;
  183. case 142: /* pop */
  184.          if (--sp < stack) error("! More pops than pushes") ;
  185.          h = sp->h ; v = sp->v ;
  186.          w = sp->w ; x = sp->x ; y = sp->y ; z = sp->z ;
  187.          break ;
  188. case 143: h += signedbyte() ; break ;
  189. case 144: h += signedpair() ; break ;
  190. case 145: h += signedtrio() ; break ;
  191. case 146: h += signedquad() ; break ;
  192. case 147: h += w ; break ;
  193. case 148: h += (w = signedbyte()) ; break ;
  194. case 149: h += (w = signedpair()) ; break ;
  195. case 150: h += (w = signedtrio()) ; break ;
  196. case 151: h += (w = signedquad()) ; break ;
  197. case 152: h += x ; break ;
  198. case 153: h += (x = signedbyte()) ; break ;
  199. case 154: h += (x = signedpair()) ; break ;
  200. case 155: h += (x = signedtrio()) ; break ;
  201. case 156: h += (x = signedquad()) ; break ;
  202. case 157: v += signedbyte() ; break ;
  203. case 158: v += signedpair() ; break ;
  204. case 159: v += signedtrio() ; break ;
  205. case 160: v += signedquad() ; break ;
  206. case 161: v += y ; break ;
  207. case 162: v += (y = signedbyte()) ; break ;
  208. case 163: v += (y = signedpair()) ; break ;
  209. case 164: v += (y = signedtrio()) ; break ;
  210. case 165: v += (y = signedquad()) ; break ;
  211. case 166: v += z ; break ;
  212. case 167: v += (z = signedbyte()) ; break ;
  213. case 168: v += (z = signedpair()) ; break ;
  214. case 169: v += (z = signedtrio()) ; break ;
  215. case 170: v += (z = signedquad()) ; break ;
  216. case 171: case 172: case 173: case 174: case 175: case 176: case 177:
  217. case 178: case 179: case 180: case 181: case 182: case 183: case 184:
  218. case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  219. case 192: case 193: case 194: case 195: case 196: case 197: case 198:
  220. case 199: case 200: case 201: case 202: case 203: case 204: case 205:
  221. case 206: case 207: case 208: case 209: case 210: case 211: case 212:
  222. case 213: case 214: case 215: case 216: case 217: case 218: case 219:
  223. case 220: case 221: case 222: case 223: case 224: case 225: case 226:
  224. case 227: case 228: case 229: case 230: case 231: case 232: case 233:
  225. case 234: case 235: case 236: case 237: case 238: /* font selection commands */
  226.          if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
  227.          else {
  228.             fnt = dvibyte() ;
  229.             while (cmd-- > 235)
  230.                fnt = (fnt << 8) + dvibyte() ;
  231.          }
  232.          curfnt = baseFonts[fnt] ;
  233.          bbcurfnt = bbaseFonts[fnt] ;
  234.          if (bbcurfnt == 0) {
  235.             bbtfmload(fnt) ;
  236.             bbcurfnt = bbaseFonts[fnt] ;
  237.          }
  238.          break ;
  239. case 243: case 244: case 245: case 246: /*fntdef1 */
  240.          skipover(cmd - 230) ;
  241.          skipover(dvibyte() + dvibyte()) ;
  242.          break ;
  243. case 239: skipover((int)dvibyte()) ; break ;
  244. case 240: skipover((int)twobytes()) ; break ;
  245. case 241: skipover((int)threebytes()) ; break ;
  246. case 242: skipover((int)signedquad()) ; break ;
  247.       }
  248.    }
  249. }
  250. void findbb() {
  251.    integer curpos = ftell(dvifile) ;
  252.    real conv = 72.0 * (real)num / (real)den * (real)mag / 254000000.0 ;
  253.    real off = 72.0 / conv ;
  254.    real margin = 1.0 / conv ;
  255.    real vsize = 792.0 / conv ;
  256.    real hadj = -72.0 * hoff / 4736286.72 ;
  257.    real vadj = 72.0 * voff / 4736286.72 ;
  258.  
  259.    fseek(dvifile, firstboploc, 0) ;
  260.    bbdopage() ;
  261.    fseek(dvifile, curpos, 0) ;
  262.    lly = vsize - 2 * off - lly ;
  263.    ury = vsize - 2 * off - ury ;
  264.    llx = (int)floor((llx + off - margin) * conv - hadj + 0.5) ;
  265.    lly = (int)floor((lly + off + margin) * conv - vadj + 0.5) ;
  266.    urx = (int)floor((urx + off + margin) * conv - hadj + 0.5) ;
  267.    ury = (int)floor((ury + off - margin) * conv - vadj + 0.5) ;
  268. /* no marks on the page? */
  269.    if (llx >= urx || lly <= ury)
  270.       llx = lly = urx = ury = 72 ;
  271. #ifdef SHORTINT
  272.    sprintf(nextstring, "%ld %ld %ld %ld", llx, ury, urx, lly) ;
  273. #else
  274.    sprintf(nextstring, "%d %d %d %d", llx, ury, urx, lly) ;
  275. #endif
  276. }
  277.